package ncrnadb.ncinetview.internal.owrapper;

import java.util.Collection;
import java.util.TreeSet;


/**
 * Three levels identifier implementation.
 * 
 * entity_type:source:id   entity_type::id   source:id   id   ::id
 * or
 * \@ORID
 * 
 * 
 * 
 * @author vbonnici
 *
 */
public class RID implements Comparable<RID>{
	
	public final static String ORIDPattern = "#[0-9]+:[0-9]+";
	//public final static String RIDPattern = "[^\\p{:}]+\\p{:}*[^\\p{:}]+\\p{:}[^\\p{:}]+";
	

	public EntityType etype = null;
	public Source source = null;
	public String id = null;
	public boolean isORID = false;
	
	public RID(){
	}
	
	
	public RID(EntityType etype, Source source, String id){
		this.etype = etype;
		this.source = source;
		this.id = id;
	}
	
	public RID(String id){
		this.id = id;
		this.isORID = true;
	}
	
	
	
	public static String normalizeAlias(String alias){
		return alias.toUpperCase().replace("-", "_").replace("\t", " ").replace(',',' ').replaceAll("\\s+", "_");
		
	}
	public static String normalize(String s){
		return s.trim().toUpperCase().replace("\t", " ").replace(',',' ').replaceAll("\\s+", "_");
	}
	
	
	private static int nofChars(char c, String s){
		int ret = 0;
		for(int i=0; i<s.length(); i++){
			if(s.charAt(i) == c)
				ret++;
		}
		return ret;
	}
	
	
	
	public static RID get(String full){
		if(full != null){
			full = full.trim();
			if(full.length() > 0){
				if(full.matches(ORIDPattern)){
//					System.out.println("RID");
					return new RID(full);
				}
				else{
					int nof = nofChars(':', full);
					if(nof == 0 && full.length()>1){
						//id
//						System.out.println("id");
						return new RID(null, null, normalizeAlias(full));
					}
					else if(nof == 1){
						// source:id
//						System.out.println("source:id");
						int ii = full.indexOf(':');
						Source source = Source.getByCompant(normalize(full.substring(0,ii)));
						if(source != null && full.length()>ii){
							return new RID(null, source, normalizeAlias(full.substring(ii+1)));
						}
					}
					else if(nof == 2){
//						System.out.println("type:source:id");
						//:::a  e:d:a e*:d*:a
						int i1 = full.indexOf(':');
						int i2 = full.indexOf(':', i1+1);
						
						if(full.length() > i2){
							EntityType etype = EntityType.getByType(normalize(full.substring(0,i1)));
							Source source = Source.getByCompant(normalize(full.substring(i1+1,i2))); 
							return new RID(etype, source, normalizeAlias(full.substring(i2+1)));
						}
					}
				}
			}
		}
		
		
		return null;
	}
	
	public static Collection<RID> getRIDs(Collection<String> as, EntityType forcedType){
		Collection<RID> rids = new TreeSet<RID>();
		for(String s : as){
			RID rid = get(s);
			if(rid != null){
				if( rid.etype == null )
					rid.etype = forcedType;
				rids.add(rid);
			}
		}
		return rids;
	}
	
	
	public String toString(){
		if(isORID)
			return id;
		
		String ee = "";
		if(etype != null)	ee = etype.type;
		String es = "";
		if(source != null) es = source.compact();
		
		return ee+":"+es+":"+id;
		
	}

	
	
//	private int compEtype(EntityType e1, EntityType e2){
//		if(e1 == null && e2 == null)	return 0;
//		else if(e1 != null && e2 == null)	return -1;
//		else if(e1 == null && e2 != null)	return 1;
//		else return e1.compareTo(e2);
//	}
//	private int compSource(Source s1, Source s2){
//		if(s1 == null && s2==null) return 0;
//		else if(s1 != null && s2==null) return -1;
//		else if(s1 == null && s2!=null) return 1;
//		else return s1.compareTo(s2);
//	}
	private <T extends Comparable<T>> int compNull(T c1, T c2){
		if(c1 == null && c2 == null) return 0;
		else if(c1 != null && c2 == null) return -1;
		if(c1 == null && c2 != null) return 1;
		return c1.compareTo(c2);
	}
	

	@Override
	public int compareTo(RID o) {
		int ret = compNull(etype, o.etype);
		if(ret == 0){
			ret = compNull(source, o.source);
			if(ret == 0)
				return compNull(id, o.id);
		}
		return ret;
	}
}

